home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
remin301.zip
/
PATCH301.ZIP
/
REM2PS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-28
|
17KB
|
580 lines
/***************************************************************/
/* */
/* REM2PS.C */
/* */
/* Print a PostScript calendar. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992 by David F. Skoll. */
/* */
/***************************************************************/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_UNISTD
#include <unistd.h>
#endif
#include "rem2ps.h"
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_PROTOS
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif
#define NEW(type) ((type *) malloc(sizeof(type)))
typedef struct _CalEntry {
struct _CalEntry *next;
char *entry;
} CalEntry;
typedef struct {
char *name;
int xsize, ysize;
} PageType;
char Days[]="SMTWTFS";
PageType Pages[] =
{
{"Letter", 612, 792}, /* 8.5 x 11 in. */
{"Tabloid", 792, 1224}, /* 11 x 17 in. */
{"Ledger", 1224, 792}, /* 17 x 11 in. */
{"Legal", 612, 1008}, /* 8.5 x 14 in. */
{"Statement", 396, 612}, /* 5.5 x 8.5 in. */
{"Executive", 540, 720}, /* 7.5 x 10 in. */
{"A3", 842, 1190},
{"A4", 595, 842},
{"A5", 420, 595},
{"B4", 729, 1032},
{"B5", 519, 729},
{"Folio", 612, 936},
{"Quarto", 612, 780},
{"10x14", 720, 1008}
};
#define NUMPAGES (sizeof(Pages)/sizeof(Pages[0]))
CalEntry *CurEntries;
PageType *CurPage;
char PortraitMode;
char NoSmallCal;
char LineBuffer[LINELEN];
char *HeadFont="Helvetica";
char *DayFont="Helvetica-BoldOblique";
char *EntryFont="Helvetica";
char *SmallFont="Helvetica";
char *LineWidth = "1";
char *HeadSize="14";
char *DaySize="14";
char *EntrySize="8";
char *BorderSize = "6";
int validfile = 0;
int CurDay;
int MaxDay;
int DayNum;
int WkDayNum;
void Init ARGS ((int argc, char *argv[]));
void Usage ARGS ((char *s));
void DoPsCal ARGS ((void));
void DoSmallCal ARGS((char *m, int days, int first, int col));
void WriteProlog ARGS ((void));
void WriteCalEntry ARGS ((void));
void WriteOneEntry ARGS ((char *s));
/***************************************************************/
/* */
/* MAIN PROGRAM */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int main(int argc, char *argv[])
#else
int main(argc, argv)
int argc;
char argv[];
#endif
{
/* If stdin is a tty - probably wrong. */
Init(argc, argv);
if (isatty(0)) {
Usage("Input should not come from a terminal");
}
/* Search for a valid input file */
while (!feof(stdin)) {
gets(LineBuffer);
if (!strcmp(LineBuffer, PSBEGIN)) {
if (!validfile) WriteProlog();
validfile++;
DoPsCal();
}
}
if (!validfile) {
fprintf(stderr, "Couldn't find any calendar data!\n");
exit(1);
}
printf("%%%%Trailer\n");
printf("%%%%Pages: %d\n", validfile);
return 0;
}
/***************************************************************/
/* */
/* DoPsCal - emit PostScript for the calendar. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
void DoPsCal(void)
#else
void DoPsCal()
#endif
{
char month[40], year[40];
char prevm[40], nextm[40];
int days, wkday, prevdays, nextdays;
int sfirst;
int i;
int smallcol;
CalEntry *c, *d;
printf("%%%%Page: %d %d\n", validfile, validfile);
/* Read the month and year name, followed by # days in month and 1st day of
month */
gets(LineBuffer);
sscanf(LineBuffer, "%s %s %d %d", month, year, &days, &wkday);
gets(LineBuffer);
sscanf(LineBuffer, "%s %d", prevm, &prevdays);
gets(LineBuffer);
sscanf(LineBuffer, "%s %d", nextm, &nextdays);
MaxDay = days;
/* Emit PostScript to do the heading */
if (!PortraitMode) printf("XSIZE 0 translate 90 rotate\n");
printf("(%s %s) doheading\n", month, year);
/* Calculate the minimum box size */
printf("/MinBoxSize ytop MinY sub 7 div def\n");
/* If wkday >= 2, then do the small calendars at the top. */
if (wkday >=2 && !NoSmallCal) {
smallcol = 0;
printf("/ysmall ytop def\n");
}
/* Do each entry */
CurEntries = NULL;
CurDay = 1;
WkDayNum = wkday;
while(1) {
gets(LineBuffer);
if (!strcmp(LineBuffer, PSEND)) break;
/* Read the day number - a bit of a hack! */
DayNum = (LineBuffer[8] - '0') * 10 + LineBuffer[9] - '0';
if (DayNum != CurDay) {
for(; CurDay<DayNum; CurDay++) {
WriteCalEntry();
WkDayNum = (WkDayNum + 1) % 7;
}
}
/* Add the text */
c = NEW(CalEntry);
if (!c) {
fprintf(stderr, "malloc failed - aborting.\n");
exit(1);
}
c->next = NULL;
c->entry = malloc(strlen(LineBuffer+10) + 1);
if (!c->entry) {
fprintf(stderr, "malloc failed - aborting.\n");
exit(1);
}
strcpy(c->entry, LineBuffer+10);
/* Put on linked list */
if (!CurEntries) CurEntries = c;
else {
d = CurEntries;
while(d->next) d = d->next;
d->next = c;
}
}
for(; CurDay<=days; CurDay++) {
WriteCalEntry();
WkDayNum = (WkDayNum + 1) % 7;
}
/* If wkday < 2, set ysmall. If necessary (only for feb) increase cal size. */
if (wkday < 2 && !NoSmallCal) {
smallcol = 5;
printf("/ysmall ylast def\n");
if (days == 28 && wkday == 0) {
printf("/ysmall ymin def /ymin ysmall MinBoxSize sub def\n");
printf("MinX ymin MaxX ymin L\n");
}
}
/* Now draw the vertical lines */
for (i=0; i<=7; i++) {
printf("%d xincr mul MinX add ymin %d xincr mul MinX add topy L\n",
i, i);
}
/* print the small calendars */
if (!NoSmallCal) {
sfirst = wkday - (prevdays % 7);
if (sfirst < 0) sfirst += 7;
DoSmallCal(prevm, prevdays, sfirst, smallcol);
sfirst = wkday + (days % 7);
if (sfirst >6) sfirst -= 7;
DoSmallCal(nextm, nextdays, sfirst, smallcol+1);
}
/* Do it! */
printf("showpage\n");
}
/***************************************************************/
/* */
/* WriteProlog - write the PostScript prologue */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
void WriteProlog(void)
#else
void WriteProlog()
#endif
{
int i;
int x = CurPage->xsize;
int y = CurPage->ysize;
if (!PortraitMode) {
i = x; x = y; y = i;
}
/* Write the document structuring stuff */
printf("%%!PS-Adobe-\n");
printf("%%%%DocumentFonts: %s", HeadFont);
if (strcmp(HeadFont, DayFont)) printf(" %s", DayFont);
if (strcmp(EntryFont, HeadFont) &&
strcmp(EntryFont, DayFont)) printf(" %s", EntryFont);
if (!NoSmallCal && strcmp(SmallFont, HeadFont) &&
strcmp(SmallFont, DayFont) &&
strcmp(SmallFont, EntryFont)) printf(" %s", SmallFont);
putchar('\n');
printf("%%%%Creator: Rem2PS\n");
printf("%%%%Pages: (atend)\n");
printf("%%%%EndComments\n");
for (i=0; PSProlog[i]; i++) puts(PSProlog[i]);
printf("/HeadFont /%s def\n", HeadFont);
if (!NoSmallCal) printf("/SmallFont /%s def\n", SmallFont);
printf("/DayFont /%s def\n", DayFont);
printf("/EntryFont /%s def\n", EntryFont);
printf("/HeadSize %s def\n", HeadSize);
printf("/DaySize %s def\n", DaySize);
printf("/EntrySize %s def\n", EntrySize);
printf("/XSIZE %d def\n", CurPage->xsize);
printf("/MinX 36 def\n");
printf("/MinY 36 def\n");
printf("/MaxX %d def\n", x-36);
printf("/MaxY %d def\n", y-36);
printf("/Border %s def\n", BorderSize);
printf("%s setlinewidth\n", LineWidth);
/* Check if smallfont is fixed pitch */
if (!NoSmallCal) {
printf("SmallFont findfont /FontInfo get /isFixedPitch get\n");
/* Define SmallString used to set smallfont size */
printf("{/SmallString (WW ) def}\n");
printf("{/SmallString (WW) def}\nifelse\n");
}
printf("%%%%EndProlog\n");
/* Set the minimum box size */
}
/***************************************************************/
/* */
/* WriteCalEntry - write all entries for one day */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
void WriteCalEntry(void)
#else
void WriteCalEntry()
#endif
{
CalEntry *c = CurEntries;
CalEntry *d;
/* Move to appropriate location */
printf("Border ytop %d xincr mul MinX add xincr\n", WkDayNum);
/* Set up the text array */
printf("[\n");
CurEntries = NULL;
while(c) {
WriteOneEntry(c->entry);
free(c->entry);
d = c->next;
free(c);
c = d;
}
printf("]\n");
/* Print the day number */
printf("(%d)\n", CurDay);
/* Do it! */
printf("DoCalBox\n");
/* Update ymin */
printf("/y exch def y ymin lt {/ymin y def} if\n");
/* If WkDayNum is a Sunday, move to next row. */
if (WkDayNum == 6 || CurDay == MaxDay) {
printf("/y ytop MinBoxSize sub def y ymin lt {/ymin y def} if\n");
/* Draw the line at the bottom of the row */
printf("MinX ymin MaxX ymin L\n");
/* Update ytop */
printf("/ylast ytop def\n");
printf("/ytop ymin def\n");
}
}
/***************************************************************/
/* */
/* WriteOneEntry - write an entry for one day */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
void WriteOneEntry(char *s)
#else
void WriteOneEntry(s)
char *s;
#endif
{
int c;
printf(" [");
/* Chew up leading spaces */
while(isspace(*s)) s++;
putchar('(');
while(*s) {
c = *s++;
if (c == '\\' || c == '(' || c == ')') putchar('\\');
if (!isspace(c)) putchar(c);
else {
putchar(')');
while(isspace(*s)) s++;
if (!*s) {
printf("]\n");
return;
}
putchar('(');
}
}
printf(")]\n");
}
/***************************************************************/
/* */
/* Init - set up parameters */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void Init(int argc, char *argv[])
#else
void Init(argc, argv)
int argc;
char *argv[];
#endif
{
char *s, *t;
int i=1;
int j;
PortraitMode = 1;
NoSmallCal = 0;
CurPage = Pages; /* Letter size by default */
while (i < argc) {
s = argv[i];
i++;
if (*s++ != '-') Usage("Options must begin with '-'");
switch(*s++) {
case 's':
if (i == argc) Usage("Size must be supplied");
t = argv[i++];
while(*s) {
switch(*s++) {
case 'h': HeadSize = t; break;
case 'e': EntrySize = t; break;
case 'd': DaySize = t; break;
default: Usage("Size must specify h, e, or d");
}
}
break;
case 'f':
if (i == argc) Usage("Font must be supplied");
t = argv[i++];
while(*s) {
switch(*s++) {
case 'h': HeadFont = t; break;
case 'e': EntryFont = t; break;
case 'd': DayFont = t; break;
case 's': SmallFont = t; break;
default: Usage("Font must specify s, h, e, or d");
}
}
break;
case 'm':
if (i == argc) Usage("Media must be supplied");
t = argv[i++];
CurPage = NULL;
for (j=0; j<NUMPAGES; j++)
if (!strcmp(t, Pages[j].name)) {
CurPage = &Pages[j];
break;
}
if (!CurPage) {
fprintf(stderr, "\nUnknown media specified.\n");
fprintf(stderr, "\nAvailable media types:\n");
for (j=0; j<NUMPAGES; j++)
fprintf(stderr, " %s\n", Pages[j].name);
exit(1);
}
break;
case 'b':
if (i == argc) Usage("Border must be supplied");
BorderSize = argv[i++];
break;
case 't':
if (i == argc) Usage("Line thickness must be supplied");
LineWidth = argv[i++];
break;
case 'l': PortraitMode = 0; break;
case 'c': NoSmallCal = 1; break;
default: Usage("Unrecognized option");
}
}
}
/***************************************************************/
/* */
/* Usage - print usage information */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void Usage(char *s)
#else
void Usage(s)
char *s;
#endif
{
if (s) fprintf(stderr, "\nrem2ps: %s\n\n", s);
fprintf(stderr, "Rem2PS: Produce a PostScript calendar from output of Remind.\n\n");
fprintf(stderr, "Usage: rem2ps [options]\n\n");
fprintf(stderr, "Options:\n\n");
fprintf(stderr, "-l Do calendar in landscape mode.\n");
fprintf(stderr, "-c Do NOT generate small calendars for previous\n");
fprintf(stderr, " and next month.\n");
fprintf(stderr, "-m media Set page size (eg, Letter, Legal, A4.) Case sensitive!\n");
fprintf(stderr, "-f[shed] font Set font for small cal, hdr, cal entries and/or day numbers.\n");
fprintf(stderr, "-s[hed] size Set size for header, calendar entries and/or day numbers.\n");
fprintf(stderr, "-b size Set border size for calendar entries.\n");
fprintf(stderr, "-t size Set line thickness.\n");
exit(1);
}
/***************************************************************/
/* */
/* DoSmallCal - do the small calendar for previous or next */
/* month. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
void DoSmallCal(char *m, int days, int first, int col)
#else
void DoSmallCal(m, days, first, col)
char *m;
int days, first, col;
#endif
{
/* Do the small calendar */
int i;
int row = 2;
/* Figure out the font size */
printf("/SmallFontSize MinBoxSize Border sub Border sub 8 div 2 sub def\n");
printf("SmallFont findfont setfont\n");
printf("SmallString stringwidth pop /SmallWidth exch def\n");
printf("SmallWidth 7 mul xincr Border sub Border sub exch div /tmp exch def\n");
printf("tmp SmallFontSize lt {/SmallFontSize tmp def} if\n");
printf("SmallFont findfont SmallFontSize scalefont setfont\n");
/* Recalculate SmallWidth */
printf("SmallString stringwidth pop /SmallWidth exch def\n");
/* Save graphics state */
printf("gsave\n");
/* Move origin to upper-left hand corner of appropriate box */
printf("%d xincr mul MinX add ysmall translate\n", col);
/* Print the month */
printf("SmallWidth 7 mul (%s) stringwidth pop sub 2 div Border add Border neg SmallFontSize sub moveto (%s) show\n", m, m);
/* Print the days of the week */
for (i=0; i<7; i++)
printf("Border %d SmallWidth mul add Border neg SmallFontSize sub SmallFontSize sub 2 sub moveto (%c) show\n", i, Days[i]);
/* Now do the days of the month */
for (i=1; i<=days; i++) {
printf("Border %d SmallWidth mul add Border neg SmallFontSize sub SmallFontSize 2 add %d mul sub moveto (%d) show\n", first, row, i);
first++;
if (first == 7) { first = 0; row++; }
}
/* restore graphics state */
printf("grestore\n");
}